﻿using FunnyArts.JSAdapter.Attri;
using FunnyArts.JSAdapter.Inter;
using FunnyArts.PrettyClient.Core.Utils;
using FunnyArts.PrettyClient.Model;
using FunnyArts.PrettyClient.Services;
using FunnyArts.PrettyClient.Services.Contracts;
using FunnyArts.PrettyClient.Settings.Controller;
using FunnyArts.PrettyClient.Settings.Model;
using FunnyArts.PrettyClient.Settings.ViewModels.Pages;
using FunnyArts.PrettyClient.Settings.Views.Pages;
using FunnyArts.PrettyClient.Settings.Views.Windows;
using FunnyArts.PrettyClient.ViewModels;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Threading.Tasks;
using System.Windows;
using Wpf.Ui;
using Wpf.Ui.Tray;

namespace FunnyArts.PrettyClient
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        private static readonly IHost _host = Host.CreateDefaultBuilder()
        .ConfigureAppConfiguration(c =>
        {
            c.AddConfiguration(SystemSettingController.LoadSetting());
            c.SetBasePath(AppContext.BaseDirectory);
        })
        .ConfigureServices(
            (_, services) =>
            {
                // App Host
                services.AddHostedService<ApplicationHostService>();

                services.AddSingleton<INotifyIconService, NotifyIconService> ();
                services.AddSingleton<ISnackbarService, SnackbarService>();
                services.AddSingleton<IContentDialogService, ContentDialogService>();

                services.AddSingleton<SystemSetting>();
                services.AddSingleton<SettingsPageVm>();
                services.AddSingleton<MainWindowVm>();

                // Main window container with navigation
                services.AddSingleton<IWindow, MainWindow>();
                services.AddSingleton<SettingsPage>();
                services.AddTransient<SettingsWindow>();
            }
        )
        .Build();

        //static App()
        //{
        //    //加载依赖
        //    AssemblyLoadContext.Default.Resolving += ResolveAssembly;
        //}
        public App()
        {
            //加载依赖
            AssemblyLoadContext.Default.Resolving += ResolveAssembly;
        }
        ///// <summary>
        ///// 系统配置
        ///// </summary>
        //public IConfiguration configuration { get; private set; }
        
        public static string[] subDirectorys => (AppContext.GetData("SubdirectoriesToProbe") as string).Split(';');

        public static T GetRequiredService<T>()
         where T : class
        {
            return _host.Services.GetRequiredService<T>();
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            Application.Current.ShutdownMode = ShutdownMode.OnLastWindowClose;
            LoggerHelper.Init(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"), "SystemLog");
            
            //加载系统配置
            //configuration = SystemSetting.LoadSetting();
            
            
            base.OnStartup(e);
        }

        private void OnExit(object sender, ExitEventArgs e)
        {
            _host.StopAsync().Wait();

            _host.Dispose();
        }

        /// <summary>
        /// 加载指定位置程序集
        /// </summary>
        /// <param name="assemblyLoadContext"></param>
        /// <param name="assemblyName"></param>
        /// <returns></returns>
        private static Assembly ResolveAssembly(AssemblyLoadContext assemblyLoadContext, AssemblyName assemblyName)
        {
            foreach (var subDirectory in subDirectorys)
            {
                var pathMaybe = Path.Combine(AppContext.BaseDirectory, subDirectory, $"{assemblyName.Name}.dll");
                if (File.Exists(pathMaybe))
                {
                    return assemblyLoadContext.LoadFromAssemblyPath(pathMaybe);
                }
            }
            return null;
        }
        

        private void OnStartup(object sender, StartupEventArgs e)
        {
            _host.Start();
        }
    }
}
